package com.hyt.it.ogt.kq.service.gov.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hyt.common.apiInfor.ApiResponse;
import com.hyt.core.base.BaseEntity;
import com.hyt.core.base.BaseServiceImpl;
import com.hyt.core.util.UUIDUtils;
import com.hyt.it.ogt.kq.common.gov.constant.CodeEnum;
import com.hyt.it.ogt.kq.common.gov.constant.ResponseCode;
import com.hyt.it.ogt.kq.common.config.exception.KqException;
import com.hyt.it.ogt.kq.service.gov.feign.pt.GovPtClient;
import com.hyt.it.ogt.kq.service.gov.mapper.TaskAreaMapper;
import com.hyt.it.ogt.kq.service.gov.model.dto.PtOfficeAreaDTO;
import com.hyt.it.ogt.kq.service.gov.model.entity.TaskArea;
import com.hyt.it.ogt.kq.service.gov.model.entity.TaskPlace;
import com.hyt.it.ogt.kq.service.gov.service.IOfficeAreaService;
import com.hyt.it.ogt.kq.service.gov.service.ITaskAreaService;
import com.hyt.it.ogt.kq.service.gov.service.ITaskPlaceService;
import com.hyt.it.ogt.kq.service.model.entity.TaskCandidateArea;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 任务区域表 服务实现类
 * </p>
 *
 * @author huangyh
 * @since 2021-04-12
 */
@Service
public class TaskAreaServiceImpl extends BaseServiceImpl<TaskAreaMapper, TaskArea> implements ITaskAreaService {

    @Resource
    private GovPtClient govPtClient;

    @Resource
    private TaskAreaMapper taskAreaMapper;

    @Resource
    private ITaskPlaceService iTaskPlaceService;

    @Resource
    private IOfficeAreaService iOfficeAreaService;

    @Override
    public List<TaskArea> getTaskProvince(String taskId) {

        LambdaQueryWrapper<TaskArea> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(TaskArea::getTaskId,taskId)
                .eq(TaskArea::getType, CodeEnum.AREA_TYPE_PROVINCE.getCode())
                .eq(TaskArea::getDelFlag,false);

        return this.list(lambdaQueryWrapper);
    }

    @Override
    public List<TaskArea> getTaskCityByProvince(String taskId, String provinceId) {
        LambdaQueryWrapper<TaskArea> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(TaskArea::getTaskId,taskId)
                .eq(TaskArea::getType, CodeEnum.AREA_TYPE_CITY.getCode())
                .eq(TaskArea::getParentId,provinceId)
                .eq(TaskArea::getDelFlag,false);

        return this.list(lambdaQueryWrapper);
    }

    @Override
    public List<TaskArea> getTaskDistrictByCity(String taskId, String cityId) {
        LambdaQueryWrapper<TaskArea> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(TaskArea::getTaskId,taskId)
                .eq(TaskArea::getType, CodeEnum.AREA_TYPE_DISTRICT.getCode())
                .eq(TaskArea::getParentId,cityId)
                .eq(TaskArea::getDelFlag,false);

        return this.list(lambdaQueryWrapper);
    }

    @Override
    public Map<String,TaskArea> getTaskAreaMap(String taskId){
        List<TaskArea> taskCandidateAreaList = this.lambdaQuery()
                .eq(TaskArea::getTaskId,taskId)
                .eq(TaskArea::getDelFlag,false)
                .select(TaskArea::getAreaId,TaskArea::getType,TaskArea::getParentId,TaskArea::getParentIds,TaskArea::getName)
                .list();
        Map<String,TaskArea> mapTaskAreaMap = new HashMap<>(taskCandidateAreaList.size());
        taskCandidateAreaList.forEach(taskArea -> mapTaskAreaMap.put(taskArea.getAreaId(),taskArea));
        return mapTaskAreaMap;
    }

    @Override
    public void initTaskArea(String taskId, String officeId) {

        Integer count = this.lambdaQuery()
                .eq(TaskArea::getTaskId,taskId)
                .eq(TaskArea::getDelFlag,false)
                .count();

        if (count <= 0) {
            //检测和初始化机构数据
            iOfficeAreaService.initOfficeArea(officeId);
            //初始化任务数据
            //baseMapper.initTaskArea(taskId,officeId);

            //初始化任务考生区域参数
            List<TaskArea> allAreaList = iOfficeAreaService.getAllAreaList();
            for (TaskArea area : allAreaList){
                area.setId(UUIDUtils.newSortUUID());
                area.setTaskId(taskId);
            }
            if(!CollectionUtils.isEmpty(allAreaList)){
                this.saveBatch(allAreaList);
            }
        }

    }

    @Override
    public List<TaskArea> listByTaskId(String taskId) {
        QueryWrapper<TaskArea> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(TaskArea::getTaskId, taskId)
                .eq(TaskArea::getDelFlag, false);
        return list(queryWrapper);
    }

    @Override
    public void copyTaskArea(String newId, String oldId, String userName) {
        taskAreaMapper.copyTaskArea(newId, oldId, userName);
    }

    /**
     * key:areaId,value:parentId
     * @param taskId
     * @return
     */
    @Override
    public Map<String,String> taskAreaMap(String taskId) {

        List<TaskArea> areaList = this.lambdaQuery()
                .eq(TaskArea::getTaskId,taskId)
                .eq(TaskArea::getDelFlag,false)
                .select(TaskArea::getAreaId,TaskArea::getParentId)
                .list();

        Map<String,String> map = new HashMap<>(areaList.size());
        areaList.stream().forEach(taskArea -> {
            map.put(taskArea.getAreaId(),taskArea.getParentId());
        });

        return map;
    }

    @Override
    public void deleteByTaskId(String taskId) {
        this.lambdaUpdate()
                .eq(TaskArea::getTaskId, taskId)
                .eq(TaskArea::getDelFlag, false)
                .set(TaskArea::getDelFlag, true)
                .update();
    }

    @Override
    public String randomGetOneDistrictId(String taskId) {
        return this.lambdaQuery()
                .eq(TaskArea::getTaskId, taskId)
                .eq(TaskArea::getType, CodeEnum.AREA_TYPE_DISTRICT.getCode())
                .eq(TaskArea::getDelFlag, false)
                .last("LIMIT 1")
                .one().getAreaId();
    }

    @Override
    public void initVirtualAreaPlace(String taskId) {

        Integer count = lambdaQuery()
                .eq(TaskArea::getTaskId,taskId)
                .eq(TaskArea::getDelFlag,false)
                .count();
        if (count > 0) {
            return;
        }

        //初始化虚拟区域
        List<TaskArea> taskAreaList = new ArrayList<>();
        //虚拟国
        TaskArea country = new TaskArea();
        country.setTaskId(taskId)
                .setAreaId("100000")
                .setName("虚拟国")
                .setType("1");
        taskAreaList.add(country);
        //虚拟省
        TaskArea province = new TaskArea();
        province.setTaskId(taskId)
                .setAreaId("100001")
                .setParentId("100000")
                .setParentIds("100000")
                .setName("虚拟省")
                .setType("2");
        taskAreaList.add(province);
        //虚拟市
        TaskArea city = new TaskArea();
        city.setTaskId(taskId)
                .setAreaId("100011")
                .setParentId("100001")
                .setParentIds("100000,100001")
                .setName("虚拟市")
                .setType("3");
        taskAreaList.add(city);
        //虚拟区县
        TaskArea district = new TaskArea();
        district.setTaskId(taskId)
                .setAreaId("100111")
                .setParentId("100011")
                .setParentIds("100000,100001,100011")
                .setName("虚拟区县")
                .setType("4");
        taskAreaList.add(district);
        if (!saveBatch(taskAreaList)) {
            throw new KqException(ResponseCode.TASK_AREA_ONLINE_INIT.getCode(), "虚拟考场初始化任务区域数据失败");
        }
        //初始化虚拟考点
        TaskPlace taskPlace = new TaskPlace();
        taskPlace.setTaskId(taskId)
                .setCode(1)
                .setName("虚拟考点")
                .setProvince("100001")
                .setCity("100011")
                .setDistrict("100111");
        if (!iTaskPlaceService.save(taskPlace)) {
            throw new KqException(ResponseCode.PLACE_AREA_ONLINE_INIT.getCode(),
                    "虚拟考场初始化任务考点数据失败");
        }
    }

    @Override
    public List<TaskArea> getCustomArea(String taskId) {
        return this.lambdaQuery()
                .eq(TaskArea::getTaskId, taskId)
                .eq(TaskArea::getFunction, CodeEnum.AREA_FUNCTION_CUSTOM.getCode())
                .eq(TaskArea::getDelFlag, Boolean.FALSE)
                .list();
    }
    
	@Override
	public List<TaskArea> listByTaskIdAndAreaIds(String taskId, List<String> areaIds) {
		 return this.lambdaQuery()
	                .eq(TaskArea::getTaskId, taskId)
	                .in(TaskArea::getAreaId, areaIds)
	                .eq(TaskArea::getDelFlag, Boolean.FALSE)
	                .list();
	}

    @Override
    public List<TaskArea> getTaskAreaList(String taskId) {
        List<TaskArea> allAreas = iOfficeAreaService.getAllAreaList();
        List<TaskArea> taskAreas = new ArrayList<>(allAreas.size());
        return taskAreas;
    }

    @Override
    public String getAreaFullName(String taskId, String district) {
        StringBuilder sb = new StringBuilder();
        TaskArea d = this.lambdaQuery().eq(TaskArea::getTaskId, taskId).eq(TaskArea::getAreaId, district).eq(BaseEntity::getDelFlag, false).last("limit 1").one();
        if(Objects.nonNull(d)) {
            sb.append("/" + d.getName());
            TaskArea c = this.lambdaQuery().eq(TaskArea::getTaskId, taskId).eq(TaskArea::getAreaId, d.getParentId()).eq(BaseEntity::getDelFlag, false).last("limit 1").one();
            if(Objects.nonNull(c)) {
                sb.insert(0, "/" + c.getName());
                TaskArea p = this.lambdaQuery().eq(TaskArea::getTaskId, taskId).eq(TaskArea::getAreaId, c.getParentId()).eq(BaseEntity::getDelFlag, false).last("limit 1").one();
                if(Objects.nonNull(p)) {
                    sb.insert(0, p.getName());
                }
            }
        }

        return sb.toString();
    }

}
